#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "Log.hpp"

using namespace LogModule;

class InetAddr
{
private:
    void Hton()
    {
        memset(&_peer, 0, sizeof(_peer));
        _peer.sin_family = AF_INET;
        _peer.sin_port = htons(_port);
        inet_pton(AF_INET, _ip.c_str(), &_peer.sin_addr.s_addr);
    }

public:
    explicit InetAddr() {}
    explicit InetAddr(const struct sockaddr_in peer)
        : _peer(peer)
    {
        // 网络转主机
        SetAddr(_peer);
    }
    explicit InetAddr(const uint16_t port, const std::string &ip)
        : _port(port), _ip(ip)
    {
        // 主机转网络
        Hton();
    }
    explicit InetAddr(const uint16_t port)
        : _port(port), _ip("0")
    {
        // 主机转网络
        Hton();
    }

    void SetAddr(const struct sockaddr_in peer)
    {
        _port = ntohs(peer.sin_port);
        char buff[64];
        inet_ntop(AF_INET, &_peer.sin_addr.s_addr, buff, sizeof(buff));
        _ip = buff;
    }

    bool operator==(const InetAddr &inetaddr) const
    {
        return (_port == inetaddr._port) && (_ip == inetaddr._ip);
    }

    // 返回本地序列的端口号
    uint16_t Port() const { return _port; }
    // 返回本地序列的点分十进制ip
    std::string Ip() const { return _ip; }
    // 返回网络地址对象指针
    const struct sockaddr_in *Peer() const { return &_peer; }
    // 返回ip+端口号拼接的字符串
    std::string AddrString() const { return _ip + ":" + std::to_string(_port); }
    // 返回网络地址大小
    socklen_t Socklen() const { return sizeof(struct sockaddr_in); }

    ~InetAddr()
    {
    }

private:
    uint16_t _port;           // 主机序列port
    std::string _ip;          // 主机ip，点分10进制
    struct sockaddr_in _peer; // 网络序列peer
};